package com.jwater.core.metrics.system;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jwater.core.metrics.FileSystemSpace;
import com.jwater.core.utils.ProcessUtils;
import com.jwater.core.utils.SysType;

import jwater.org.springframework.util.StringUtils;

/**
 * @description:磁盘信息获取
 * @author: jnner
 * @createDate: 2021/2/5
 * @version: 1.0
 */
public class DiskMetric {
    protected static Logger logger = LoggerFactory.getLogger(DiskMetric.class);

    public static final double kkk = 1024 * 1024 * 1024;
    public static final double kk = 1024 * 1024;

    /**
     * 磁盘空间使用率
     *
     * @return
     */
    public static Map<String, FileSystemSpace> getFileSystemSpace() {
        String sysType = SysType.getSysType();
        if (SysType.WINDOWS.equals(sysType)) {
            return getFileSystemSpaceForWin();
        } else if (SysType.LINUX.equals(sysType)) {
            return getFileSystemSpaceForLinux();
        }
        return new HashMap<String, FileSystemSpace>();
    }

    private static Map<String, FileSystemSpace> getFileSystemSpaceForWin() {
        Map<String, FileSystemSpace> map = new HashMap<String, FileSystemSpace>();
        File[] roots = File.listRoots();// 获取磁盘分区列表
        for (File r : roots) {
            map.put(r.getAbsolutePath(), new FileSystemSpace(r.getTotalSpace() / kkk,
                    (r.getTotalSpace() - r.getFreeSpace()) / kkk, r.getFreeSpace() / kkk));
        }
        return map;
    }

    private static Map<String, FileSystemSpace> getFileSystemSpaceForLinux() {
        Map<String, FileSystemSpace> map = new HashMap<String, FileSystemSpace>();
        try {
            List<String> lines = ProcessUtils.cmd(null, "df");
            int i = 0;
            double totalSpace, usedSpace, freeSpace;
            for (String line : lines) {
                line = line.trim();
                if (i > 0) {
                    String[] items = line.split("\\s+");
                    totalSpace = Double.parseDouble(items[1]);
                    usedSpace = Double.parseDouble(items[2]);
                    freeSpace = Double.parseDouble(items[3]);
                    map.put(items[5], new FileSystemSpace(totalSpace / kk, usedSpace / kk, freeSpace / kk));
                }
                i++;
            }
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }
        return map;
    }

    /**
     * 磁盘IO速率
     *
     * @return
     */
    public static Map<String, String> getDiskRate() {
        String sysType = SysType.getSysType();
        if (SysType.WINDOWS.equals(sysType)) {
            return getDiskRateForWin();
        } else if (SysType.LINUX.equals(sysType)) {
            return getDiskRateForLinux();
        }
        return new HashMap<String, String>();
    }

    private static Map<String, String> getDiskRateForWin() {
        Map<String, String> map = new HashMap<String, String>();
        try {
            String procCmd = System.getenv("windir") + "//system32//wbem//wmic.exe "
                    + "path Win32_PerfFormattedData_PerfDisk_LogicalDisk get AvgDiskBytesPerRead,AvgDiskBytesPerWrite,Name /value";
            List<String> result = ProcessUtils.cmd(null, procCmd);
            int i = 0;
            String read = "";
            String write = "";
            String name = "";
            for (String msg : result) {
                msg = msg.trim();
                if (StringUtils.isEmpty(msg)) {
                    continue;
                }
                i++;
                String[] items = msg.split("=");
                if ("AvgDiskBytesPerRead".equals(items[0])) {
                    read = items[1];
                } else if ("AvgDiskBytesPerWrite".equals(items[0])) {
                    write = items[1];
                } else if ("Name".equals(items[0])) {
                    name = items[1];
                }
                if (i % 3 == 0) {
                    map.put(name, Integer.parseInt(read) * 1.0 / 8 + "K," + Integer.parseInt(write) * 1.0 / 8 + "K");
                }
            }
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }
        return map;
    }

    private static Map<String, String> getDiskRateForLinux() {
        // iostat命令
        Map<String, String> map = new HashMap<String, String>();
        try {
            int i = 0;
            List<String> lines = ProcessUtils.cmd(null, "iostat -d");
            for (String line : lines) {
                if (!StringUtils.isEmpty(line)) {
                    if (i >= 2) {
                        String[] items = line.split("\\s+");
                        map.put(items[0], items[2] + "," + items[3]);
                    }
                    i++;
                }
            }
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }
        return map;
    }
}
